package com.kitty.game.house.service;


import com.kitty.common.model.Reason;

import com.kitty.common.utils.SpringUtils;
import com.kitty.game.bag.message.RespIconCartoon;
import com.kitty.game.bag.message.RespStore;
import com.kitty.game.bag.model.StoreEquipInfo;
import com.kitty.game.config.NPC;
import com.kitty.game.enter.FiedValue;
import com.kitty.game.enter.RespUpdate;
import com.kitty.game.equip.message.RespNotifyMiscEx;
import com.kitty.game.equip.model.RoleEquip;
import com.kitty.game.equip.model.RoleEquipField;
import com.kitty.game.equip.service.EquipService;
import com.kitty.game.house.message.*;
import com.kitty.game.house.model.FurnitureInfo;
import com.kitty.game.house.model.House;

import com.kitty.game.luoshu.model.Luoshu;
import com.kitty.game.npc.message.RespNpcContent;
import com.kitty.game.npc.message.RespPlayInstruction;
import com.kitty.game.onlinemall.service.MallService;
import com.kitty.game.role.model.Role;
import com.kitty.listener.EventType;
import com.kitty.listener.annotation.EventHandler;
import com.kitty.listener.event.EnterMapEvent;
import com.kitty.listener.event.LoginEvent;

import com.kitty.mina.cache.DataCache;
import com.kitty.mina.message.MessagePusher;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.json.Json;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;

@Service
public class HouseService {


    private Logger logger = LoggerFactory.getLogger(HouseService.class);
    private static final String LOG_DATE_FORMAT = "yyyy-MM-dd HH:mm";
    @Autowired
    Dao dao;

    @Autowired
    EquipService equipService;


    @EventHandler(EventType.ENTER_MAP)
    public void handleEnterMapEvent(EnterMapEvent enterMapEvent) {
        Role role = enterMapEvent.getRole();
        int mapId = role.getPos().getMapId();
//        logger.error("进入地图时在不在房屋内={}", Json.toJson(role.getPos()));
        if( mapId==28101 || mapId==28201 || mapId == 28301){
            openFurnitureStore(role);
        }

    }
    @EventHandler(EventType.LOGIN)
    public void handleEnterMapEvent1(LoginEvent loginEvent) {
        Role role = loginEvent.getRole();
        int mapId = role.getPos().getMapId();
//        logger.error("登录时在不在房屋内={}", Json.toJson(role.getPos()));
        if( mapId==28101 || mapId==28201 || mapId == 28301){
            openFurnitureStore(role);
        }

    }


    /**
     * 摆放家具
     * @param role
     * @param reqHousePlaceFurniture
     */
    public void placeFurniture(Role role, ReqHousePlaceFurniture reqHousePlaceFurniture){

        int pos = reqHousePlaceFurniture.getPos();
        RoleEquip roleEquip = equipService.getRoleEquipByPos(role, pos);

        logger.debug("获取到家具信息=={}", Json.toJson(roleEquip));

        //摆放后要占用一个位置，更改占位空间
        roleEquip.getFields().get((short) 1).getField().get((short) 335).setValue((short)1);
        sendStore((short)pos, role, roleEquip, "furniture_store");

        RespHouseFurnitureOper respHouseFurnitureOper = new RespHouseFurnitureOper();
        respHouseFurnitureOper.setHouseId(role.getExtendBox().getHouseId());
        respHouseFurnitureOper.setMapIndex(724);
        respHouseFurnitureOper.setCookie(reqHousePlaceFurniture.getCookie());
        respHouseFurnitureOper.setAction("place");
        respHouseFurnitureOper.setResult(0);
        respHouseFurnitureOper.setPos(pos);
        respHouseFurnitureOper.setId(0);
        respHouseFurnitureOper.setBx(reqHousePlaceFurniture.getBx());
        respHouseFurnitureOper.setBy(reqHousePlaceFurniture.getBy());
        respHouseFurnitureOper.setFlip(reqHousePlaceFurniture.getFlip());
        respHouseFurnitureOper.setX(reqHousePlaceFurniture.getX());
        respHouseFurnitureOper.setY(reqHousePlaceFurniture.getY());
        respHouseFurnitureOper.setDurability((short)-1);
        respHouseFurnitureOper.setIsMy((byte) 1);
        MessagePusher.pushMessage(role, respHouseFurnitureOper);

        logger.debug("发送家具操作=={}", Json.toJson(respHouseFurnitureOper));

        RespHouseData houseData = new RespHouseData();
        houseData.setHouseId(role.getExtendBox().getHouseId());
        houseData.setHouseType(role.getExtendBox().getHouse().getHouseType());
        houseData.setHousePrefix(role.getExtendBox().getHouse().getHousePrefix());
        houseData.setComfort(role.getExtendBox().getHouse().getComfort());
        houseData.setCleanliness(role.getExtendBox().getHouse().getCleanliness());
        houseData.setCleanCostTime(role.getExtendBox().getHouse().getCleanCostTime());
        houseData.setStoreType(role.getExtendBox().getHouse().getStoreType());
        MessagePusher.pushMessage(role, houseData);
        logger.debug("发送居所信息=={}", Json.toJson(houseData));
    }

    /**
     * 打开家具仓库
     * @param role
     */
    public void openFurnitureStore(Role role){

        //MSG_HOUSE_FURNITURE_DATA
        RespHouseFurnitureData respHouseFurnitureData = new RespHouseFurnitureData();
        respHouseFurnitureData.setHouseId(role.getExtendBox().getHouseId());
        MessagePusher.pushMessage(role, respHouseFurnitureData);
        logger.debug("推送家具信息");
    }

    public Luoshu getLuoshudata(int role_id) {
        Luoshu luoshu = (Luoshu)this.dao.fetch(Luoshu.class, Cnd.where("role_id", "=", role_id));
        return luoshu;
    }


    /**
     * 购买居所操作
     * @param role
     * @param house
     */
    public void buyHouse(Role role, House house) {


        if(role.getMoney() < house.getPrice()){
            MessagePusher.pushMessage(role, new RespNotifyMiscEx("金钱不足"));
            return;
        }
        SpringUtils.getRoleService().subtractMoney(role, house.getPrice(), Reason.BUY_HOUSE);
        role.getExtendBox().setHouseId(house.getHouseId());
        role.getExtendBox().setHouse(house);
        role.save();

        //刷新角色 添加居所信息
        List<FiedValue> list = new ArrayList<>();
        list.add(new FiedValue(250, house.getHouseId()));
        RespUpdate respUpdate = new RespUpdate();
        respUpdate.setRoleId(role.getRoleId());
        respUpdate.setList(list);
        MessagePusher.pushMessage(role, respUpdate);

//        SpringUtils.getRoleService().refreshRole(role);

        //TODO MSG_ACHIEVE_CONFIG = 32949;                // 服务器通知成就配置
        //TODO MSG_ACHIEVE_FINISHED = 32955;        //成就展示结束

        //done -MSG_NOTIFY_MISC_EX = 20481;//提示
        MessagePusher.pushMessage(role, new RespNotifyMiscEx("你花费#R"+house.getPrice()+"#n文钱#n，成功购买了#Y"+ house.getHouseName()+"#n"));

        //done 演示指导动画 MSG_PLAY_INSTRUCTION = 40965;--70
        RespPlayInstruction respPlayInstruction = new RespPlayInstruction();
        respPlayInstruction.setType((short) 70);
        MessagePusher.pushMessage(role,respPlayInstruction);

        //TODO MSG_HOUSE_CUR_ARTIFACT_PRACTICE = 45332;       // 服务端发送的法宝修炼数据
        //4D 5A 00 00 00 00 00 00 00 17 B1 14
        //00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

//        RespHouseData respHouseData = new RespHouseData();
//        respHouseData.setHouseId(house.getHouseId());
//        respHouseData.setHouseType(house.getHouseType());
//        respHouseData.setHousePrefix(role.getName());
//        respHouseData.setComfort((short) 10);
//        respHouseData.setCleanliness((byte) 10);
//        respHouseData.setCleanCostTime((byte) 0);
//        respHouseData.setStoreType((byte) 1);
//        MessagePusher.pushMessage(role, respHouseData);

//        RespGeneralNotify respGeneralNotify = new RespGeneralNotify();
//        respGeneralNotify.setNotify((short) NotifyModules.NOTIFY_OPEN_DLG); //对话框
//        respGeneralNotify.setValue("HomeInDlg");
//        MessagePusher.pushMessage(role, respGeneralNotify);
    }



    /**
     *  郝艾佳处
     * @param role
     * @param npc
     * @param msg
     */
    public void toBuyHouse(Role role, NPC npc, String msg){

//        MessagePusher.pushMessage(role,new RespNotifyMiscEx("未开放"));
//        return;
        String content = "";
        String head = "请选择你要购买的居所类型" ;

        head += "[小舍(1000万文钱)/buy_house_1][雅筑(5000万文钱)/buy_house_2][豪宅(1亿文钱)/buy_house_3]";
        String tail = head + "[离开]";

        logger.debug("tail="+ tail);

        RespNpcContent respNpcContent = new RespNpcContent();
        respNpcContent.setNpcName(npc.getName());
        respNpcContent.setNpcId((int) npc.getId());
        respNpcContent.setContent(tail);
        respNpcContent.setNpcIcon(npc.getIcon());
        MessagePusher.pushMessage(role, respNpcContent);
    }
    public void buyHouse1(Role role, NPC npc, String msg){

        buyHouse(role,"小舍",10000000);
    }
    public void buyHouse2(Role role, NPC npc, String msg){
        buyHouse(role,"雅筑", 50000000);
    }
    public void buyHouse3(Role role, NPC npc, String msg){
        buyHouse(role,"豪宅", 100000000);
    }
    private void buyHouse(Role role,String houseName, int price){
        logger.debug("开启购买居所窗口");
        RespOpenModifyHouseSpace respOpenModifyHouseSpace = new RespOpenModifyHouseSpace();
        respOpenModifyHouseSpace.setAction("buy");
        respOpenModifyHouseSpace.setCurHouse(houseName);
        respOpenModifyHouseSpace.setLastHouse("");
        respOpenModifyHouseSpace.setPrice(price);
        respOpenModifyHouseSpace.setBedRoom((byte) 1);
        respOpenModifyHouseSpace.setStoreRoom((byte) 1);
        respOpenModifyHouseSpace.setArtifactRoom((byte) 1);
        respOpenModifyHouseSpace.setPracticeRoom((byte) 1);
        logger.debug(respOpenModifyHouseSpace.toString());
        MessagePusher.pushMessage(role, respOpenModifyHouseSpace);
    }


    /**
     * 初始化加载家具信息
     */
    public void initFurniture() {
        logger.error("开始初始化家具信息...");
        DataCache.FURNITURE_DATA.clear();
        List<FurnitureInfo> list = dao.query(FurnitureInfo.class, Cnd.NEW());
        for (FurnitureInfo info : list) {
//            List<FurnitureInfo> newcomerGifts = DataCache.FURNITURE_DATA.computeIfAbsent(info.getIcon(), k -> new ArrayList<>());
//            newcomerGifts.add(newcomerGift);
            DataCache.FURNITURE_DATA.put(info.getIcon(),info);
        }
    }

    public FurnitureInfo getFurnitureByIcon(int icon){

        return DataCache.FURNITURE_DATA.getOrDefault(icon,null);
    }

    /**
     * 购买家具
     * @param role
     * @param icon
     * @param num
     */
    public void buyFurniture(Role role, int icon, byte num){
        FurnitureInfo furnitureInfo = getFurnitureByIcon(icon);
        if(furnitureInfo == null){
            MessagePusher.pushMessage(role,new RespNotifyMiscEx("家具信息错误"));
            return;
        }
        logger.debug("furnitureInfo=={}",Json.toJson(furnitureInfo));
        if(furnitureInfo.getName().equals("天地灵石")){
            addFurniture(role,furnitureInfo);
            MessagePusher.pushMessage(role,new RespNotifyMiscEx("天地灵石购买成功"));
            return;
        }
        if(furnitureInfo.getPurchase_cost() <= 0){
            logger.debug("售价小于0");
            return;
        }
        //成本
        int cost = furnitureInfo.getPurchase_cost() * num;
        if(cost <=0 ){
            return;
        }
        if(furnitureInfo.getPurchase_type() == 0){
            MessagePusher.pushMessage(role,new RespNotifyMiscEx("该物品不支持购买"));
            return;
        }
        if(furnitureInfo.getPurchase_type() == 1){


            if(role.getGold()< cost){
                MessagePusher.pushMessage(role,new RespNotifyMiscEx("金元宝不足"));
                return;
            }
            SpringUtils.getRoleService().subtractGold(role,cost,Reason.BUY_FURNITURE);

        }
        else if(furnitureInfo.getPurchase_type() == 2){

            if(role.getSiver() < cost){
                MessagePusher.pushMessage(role,new RespNotifyMiscEx("银元宝不足"));
                return;
            }
            SpringUtils.getRoleService().subtractSiver(role,cost,Reason.BUY_FURNITURE);
        }

        //购买成功 MSG_STORE = 61677;//F0 ED仓库

        addFurniture(role,furnitureInfo);
        MessagePusher.pushMessage(role,new RespNotifyMiscEx("购买成功"));
    }

    public void addFurniture(Role role, FurnitureInfo furnitureInfo){

        short pos = getFurnitureStorePos(role);
        if (pos != -1) {
            RoleEquip roleEquip = new RoleEquip();
            roleEquip.setType("家具");

            int id = SpringUtils.getBean(MallService.class).getRoleEquipId();
            roleEquip.setId(id);
            roleEquip.setName(furnitureInfo.getName());
            roleEquip.setRoleId(role.getRoleId());
            roleEquip.setPosition(pos);
            // 添加物品信息
            {
                RoleEquipField roleEquipField = new RoleEquipField();
                roleEquipField.setType((short) 1);
                LinkedHashMap<Short, FiedValue> basicAttrNew = getFurnitureBasicAttr(roleEquip, furnitureInfo);
                roleEquipField.setField(basicAttrNew);

                roleEquip.getFields().put(roleEquipField.getType(), roleEquipField);
            }

            RespIconCartoon respIconCartoon = new RespIconCartoon();
            respIconCartoon.setName(roleEquip.getName());
            respIconCartoon.setParam(roleEquip.getId() + "");
            MessagePusher.pushMessage(role, respIconCartoon);
//            refreshRoleEquip(role, roleEquip);
            equipService.add(role, roleEquip);


            equipService.setPositionNull(role, (byte) roleEquip.getPosition());//消失背包时装
            roleEquip.setPosition(pos);
            role.save();
            sendStore(pos, role, roleEquip, "furniture_store");
            logger.error("购买成功");
        }
    }

    public LinkedHashMap<Short, FiedValue> getFurnitureBasicAttr( RoleEquip roleEquip,  FurnitureInfo furnitureInfo) {
        LinkedHashMap<Short, FiedValue> linkedHashMap = new LinkedHashMap<>();
        List<FiedValue> values = new ArrayList<>();
        values.add(new FiedValue(206, 4));
        values.add(new FiedValue(335, 0));
        values.add(new FiedValue(74, 671557408));//物品类型 item_type
        values.add(new FiedValue(207, furnitureInfo.getSell_price()));//出手价格
        values.add(new FiedValue(1, furnitureInfo.getName()));
        values.add(new FiedValue(209, "金色"));
        values.add(new FiedValue(84, roleEquip.getId()));
        values.add(new FiedValue(270, 2));
        values.add(new FiedValue(203, 1));//数量
        values.add(new FiedValue(42, -1));//耐久度
        values.add(new FiedValue(282, 1));//combined

        values.add(new FiedValue(40, furnitureInfo.getId()));//ICON
        values.add(new FiedValue(306, String.valueOf(roleEquip.getId())));
//
//        values.add(new FiedValue(202, equip.getPosition()));//装备位置
//        values.add(new FiedValue(264, ""));
//        values.add(new FiedValue(38, 0));
//
//        values.add(new FiedValue(215, 0));//MAX_REQ_LEVEL
//        values.add(new FiedValue(34, 0));

        values.forEach(value -> linkedHashMap.put(value.getType(), value));
        return linkedHashMap;
    }

    public void sendStore(short pos, Role role, RoleEquip roleEquip, String type) {
        RespStore respStore = new RespStore();
        respStore.setStr(type);
        ArrayList<StoreEquipInfo> arrayList = new ArrayList<>();
        respStore.setList(arrayList);
        StoreEquipInfo storeEquipInfo = new StoreEquipInfo();
        storeEquipInfo.setPos(pos);
        arrayList.add(storeEquipInfo);
        storeEquipInfo.setPos(roleEquip.getPosition());
        storeEquipInfo.setEquipFields(equipService.transferList(roleEquip.getFields()), equipService.transferList2(roleEquip.getHunQiFields()));
        MessagePusher.pushMessage(role, respStore);
        logger.debug("respStore=={}",Json.toJson(respStore));
    }

    /**
     * 获得位置  furniture_store
     * @param role
     * @return
     */
    public short getFurnitureStorePos(Role role) {
        //FURNITURE_STORE_START = 3001
        //FURNITURE_STORE_COUNT = 500
        short min = 3001, max = 3500;
//        if (type.equals("furniture_store")) {
//            min = 3001;
//            max = 3500;
//        }
        for (short i = min; i < max; i++) {
            RoleEquip roleEquip = equipService.getRoleEquipByPos(role, i);
            if (roleEquip == null) {
                return i;
            }
        }
        return -1;
    }
}
